package abacab.router;

import abacab.actor.Actor;
import abacab.actor.ActorDef;
import abacab.exec.MessageExecutor;
import abacab.message.Envelope;
import abacab.ref.AbstractActorRef;

/**
 * Represents a router for messages.<br />
 * It provides the ability to:
 * <ul>
 * <li>route messages to various actors, parallel work</li>
 * <li>chose a suitable actor for a particular data in the message</li>
 * <li>...</li>
 * </ul>
 * 
 * @param <M>
 *          the type of handled messages
 */
public interface Router<M> {
	/**
	 * Initialize the router for a particular reference the router.<br />
	 * This method is for inner use only. You should never have to call it.
	 * 
	 * @param actorRef
	 *          the actor reference
	 * @param definition
	 *          the actor's definition
	 */
	void init(AbstractActorRef<M> actorRef, ActorDef<M> definition);

	/**
	 * @return the actors behind the router
	 */
	Actor<? super M>[] getActors();

	/**
	 * Send the message for execution
	 * 
	 * @param executor
	 *          the executor
	 * @param message
	 *          the message
	 */
	void send(MessageExecutor executor, Envelope<M> message);
}